Skip to content

feat(image-editor): Note + Frame + Path Selection + recover Hand/Fullscreen fix#45

Merged
lyfuci merged 2 commits intomainfrom
feat/image-editor-note-frame-pathsel
Apr 25, 2026
Merged

feat(image-editor): Note + Frame + Path Selection + recover Hand/Fullscreen fix#45
lyfuci merged 2 commits intomainfrom
feat/image-editor-note-frame-pathsel

Conversation

@lyfuci
Copy link
Copy Markdown
Owner

@lyfuci lyfuci commented Apr 25, 2026

Summary

Round out the PS palette with three more functional tools, plus recover the focus-button + Hand-tool fix that didn't make it into PR #44 (the commit landed after the merge cut).

New tools

  • Note (N) — click to drop a sticky-note marker. New `NoteShape` renders as a 16-px folded-corner pentagon with a one-line preview label below. Notes are gated on `liveCanvas`, so they appear on screen but never bake into PNG / JPEG / WebP exports — they're a pure annotation aid.
  • Frame — drag a rectangle to place a placeholder frame. New `FrameShape` renders as a dashed grey rect with a diagonal X across it (PS Frame Tool's empty-frame visual). Resizable via the standard 4 corner handles. Visible in export.
  • Path Selection (A) — un-stubbed and aliased to the Move tool's pick-and-move behaviour. Until the Pen tool ships, it functions identically to the no-tool selection arrow; full anchor-level path selection follows when vectors land.

These three tools were registered in `STUB_TOOLS` and the `Tool` type union but had never been rendered in the palette. This PR adds the palette entries (with PS-aligned icons: `StickyNote`, `LayoutTemplate`, `MousePointer`) and wires the full implementation.

Bundled UX fix (recovered from PR #44)

The focus-button + Hand-tool wiring commit landed on the branch after the merge cut, so it never reached main. Cherry-picked here:

  • F shortcut unbound (Photoshop's F cycles screen modes — keeping our F bound to focus-mode collided with muscle memory).
  • Green Fullscreen button in the tab strip's right corner (turns red when active, indicating "click to exit").
  • Hand tool (H) is no longer a stub — selecting it puts the editor into pan mode (same as holding Space).

State + render changes

  • types.ts: `NoteShape` + `FrameShape` added to the `Shape` union. `Project` files round-trip both via the existing `serializeProject` (no schema bump needed — the union is a tagged variant).
  • drawing.ts: `drawNote` (sticky-note pentagon + folded-corner shadow + preview label) and `drawFrame` (dashed rect + diagonal X + optional name).
  • hit.ts: bbox + (frame-only) corner handles. Note bbox covers the 16-px icon footprint so users can click to select it.
  • transform.ts: translate covers both shapes; resize covers frame.
  • render.ts: skips note layers in the layer loop when `!input.liveCanvas`.
  • LayersPanel.tsx: `layerLabelKey` gains note + frame branches so the right-sidebar layer list shows readable names.

STUB_TOOLS shrinks

Before: spotHeal, stamp, historyBrush, pen, arrowPath, frame, note  (+ hand on main)
After:  spotHeal, stamp, historyBrush, pen

Pen is the next deep PR; spotHeal / stamp / historyBrush all share the "sample source pixels" infrastructure and will land together as the final palette PR.

Keyboard

  • `A` → Path Selection
  • `N` → Note
  • `H` → Hand (now functional)
  • `F` → unbound (was focus toggle)

Test plan

  • Note (N): click → text prompt → sticky-note appears with preview label. Export PNG → note not present in exported file.
  • Frame: drag a rect → dashed-X placeholder appears. Resize via corner handles. Export PNG → frame is present.
  • Path Selection (A): click an existing layer → it selects + moves like the regular Move tool.
  • Hand (H): cursor becomes grab; drag pans the canvas. Same as holding Space.
  • F key does nothing.
  • Green ⛶ Fullscreen button → UI hides; button turns red ⛶ Exit fullscreen. Click again or Esc to exit.
  • Save .json → reload — notes + frames round-trip.
  • Right sidebar layer list: notes show as "Note", frames show as "Frame".

🤖 Generated with Claude Code

lyfuci and others added 2 commits April 25, 2026 16:32
UX adjustments shipped alongside the lasso/wand bundle:

- Remove the F keyboard shortcut for focus mode. Photoshop's F cycles
  screen modes, not "toggle fullscreen UI" — keeping our F bound to a
  different behaviour conflicted with users' muscle memory. F is now
  unbound, available for a future PS-aligned screen-mode cycle.
- The existing focus toggle in the tab strip becomes a prominent green
  button (red when active, indicating "click to exit"). i18n labels
  swap to "Fullscreen" / "Exit fullscreen" so it's immediately clear
  what the button does.
- Hand tool (H) is no longer a stub — it now flips the editor into pan
  mode while the tool is active, behaving exactly like holding Space.
  Removed `hand` from STUB_TOOLS, dropped the `stub: true` flag in the
  palette, added a new `effectivePanMode = panMode || tool === 'hand'`
  derivation, and routed it to both Workspace and Canvas. New OptionsBar
  hint variant + i18n string `handHint`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…palette)

Three more PS-palette tools join end-to-end, plus the missing palette
entries that were never rendered alongside their stub registrations.

- **Note (N)** — click to drop a sticky-note marker. New `NoteShape`
  renders as a 16-px folded-corner pentagon in any colour with a
  one-line preview label below. Notes are gated on `liveCanvas`, so
  they appear on screen but never bake into PNG / JPEG / WebP exports.
  Move-only; no resize handles.
- **Frame** — drag a rectangle to place a placeholder frame. New
  `FrameShape` renders as a dashed grey rect with a diagonal X across
  it (PS Frame Tool's empty-frame visual). Resizable via the standard
  4 corner handles. Visible in export.
- **Path Selection (A)** — un-stubbed and aliased to the Move tool's
  pick-and-move behaviour. Until the Pen tool ships, it functions
  identically to the no-tool selection arrow; full anchor-level path
  selection follows when vectors land.

Implementation surface:

- types.ts: NoteShape + FrameShape added to the Shape union.
- drawing.ts: drawNote (sticky-note pentagon + folded corner shadow +
  preview label), drawFrame (dashed rect + diagonal X + optional name).
- hit.ts: bbox + (frame-only) corner handles. Note bbox covers the
  16-px icon footprint so users can click to select it.
- transform.ts: translate covers both; resize covers frame.
- render.ts: skips note layers when not on the live canvas, so they
  never bake into export.
- Canvas.tsx: note (click → window.prompt → commit) sits alongside the
  other click-only tools (eyedropper / wand). Frame (drag → commit)
  joins the existing rect-like switch. arrowPath shares the
  pick-and-move codepath with 'none', including hover cursor.
- ToolsPalette.tsx: imports `LayoutTemplate`, `MousePointer`,
  `StickyNote`; arrowPath joins the vector group, frame + note join
  the annotation group. (Stub registrations for these existed in
  STUB_TOOLS already but they had never been rendered.)
- tool-meta.ts: STUB_TOOLS shrinks to the four pixel-source tools
  (spotHeal / stamp / historyBrush / pen) that still need their own PR.
- LayersPanel.tsx: layerLabelKey switch gains note + frame branches so
  the right-sidebar layer list shows readable names.
- OptionsBar.tsx: hint variants for note / frame / arrowPath.
- ImageEditor.tsx: keyboard map gains 'a' → arrowPath, 'n' → note.
- i18n: noteHint / notePrompt / frameHint / arrowPathHint plus
  annoLabel.note / annoLabel.frame in both en + zh-CN.

Bundles the cherry-picked focus-button + Hand-tool fix from PR #44 (the
commit landed after the merge cut, so it never reached main on its own).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lyfuci lyfuci merged commit 229fc3b into main Apr 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant